/* 
Copyright (c) 2004,2005, 2006, 2007, 2008 University of Illinois 

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.

3. The name of the author may not be used to endorse or promote products
   derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

//This used to list only map elements - now it handles UL's/OL's with links
//The filename can change at some later date

AccessibilityExtension.ns(function() { with (AccessibilityExtension.LIB) {

	var AE = AccessibilityExtension.ns;  
	AE.dialogName = "accessext-form-list-imgMaps";
	
	function imageMapItemDisplayDetails() {}
	imageMapItemDisplayDetails.prototype = {
		dataElementNames : ['order','linkText','linkHREF','alt','redundantText'],
		columnHeaders : ['column.header.order.label','column.header.linkText.label','column.header.link.label','column.header.alt.label','column.header.redundanttextlink.label'],
		
		accessIssuesDataElementNames : ['missingalt', 'emptyalt'],
		accessIssuesMessages : ['imagemaps.msg.missingalt', 'imagemaps.msg.emptyalt'],
	}
	var imageMapItemDisplayDetails = new imageMapItemDisplayDetails();
	
	function imageMapItem(node,order) {
		this.order = order;
		this.parse(node);
	}
	imageMapItem.prototype = {
		node : null,
		order : false,
		linkText : "",
		linkHREF : "",
		alt : "",
		redundant : false,
		redundantText : "",
		missingRedundantTextLink : false,
		missingalt: false,
		emptyalt : false,
		valid : false,
		display: true,
		displayDetails: imageMapItemDisplayDetails,
		parse : function(node) {
			this.node = node;
			this.linkText = GetValueFromAttributes(this.node,['title','alt'],false);
			if (this.linkText == false) {
				this.linkText = getDisplayableTextRecursively(this.node);
				if (this.linkText == '') {
					this.linkText = accessext_getBundleSingleString('none');
				}
			}
			if (this.node.hasAttribute('alt')) {
				this.alt = GetValueFromAttributes(this.node,['alt'],'');
				if (this.alt == '') {
					this.alt = accessext_getBundleSingleString('none');
					this.emptyalt = true;
				}
			} else {
				this.missingalt = true;
				this.emptyalt = true;
			}
			if (this.node.hasAttribute('href')) {
				this.linkHREF = GetValueFromAttributes(this.node,['href'],"");
				this.redundant = this.docHasRedundantTextLink();
				this.valid = true;
			} else {
				this.valid = false;
			}
			this.missingRedundantTextLink = !this.redundant;
		},
		docHasRedundantTextLink : function() {
			var nodes = getAllXpathResultNodes(this.node.ownerDocument.documentElement,"//a[@href=\'"+this.linkHREF+"\']");
			if (nodes.length > 1) {
				return true;
			} else if (nodes.length == 1) {
				return !(nodes[0].isSameNode(this.node));
			} else {
				return false;
			}
		},
		getTreeItem : function(windoc) {
			this.redundantText = this.redundant;
			return accesxt_generateTreeboxResults(windoc,this);
		}
	}
	
	function imageMapDisplayDetails() {}
	imageMapDisplayDetails.prototype = {
		dataElementNames : ['icita07', 'icita08','order', 'baseuri','title'],
		columnHeaders : ['column.header.icita07.label', 'column.header.icita08.label','column.header.order.label','column.header.baseuri.label','column.header.map.label'],
		
		accessIssuesDataElementNames : ['missingRedundantTextLink','missingalt', 'emptyalt'],
		accessIssuesMessages : ['imagemaps.msg.missingRedundantTextLink','imagemaps.msg.missingalt', 'imagemaps.msg.emptyalt'],
	}
	var imageMapDisplayDetails = new imageMapDisplayDetails();
	
	function imageMap(node,order) {
		this.node = node;
		this.order = order;
		if (node.hasAttribute("usemap")) {
			this.mapName = node.getAttribute("usemap");
	
			// Strip leading # from usemap if it exists
			if(this.mapName.charAt(0) == "#") {
				this.mapName = this.mapName.slice(1);
			} 		
			
			this.mapNode = this.findMapNode(this.node.ownerDocument,this.mapName);
			if (this.mapNode != null) {
				this.parseNode();
			}
		}
	}
	imageMap.prototype = {
		id : "",
		node : null,//the img
		baseuri : " ",
		mapNode : null,//the map
		mapName : null,
		icita07 : "",
		icita08 : "",
		order : false,
		title : "",
		alt : "",
		items : null,
		valid : false,
		missingRedundantTextLink : false,
		missingalt: false,
		emptyalt : false,
		display: true,
		displayDetails: imageMapDisplayDetails,
		findMapNode : function(docElement,mapName) {
			var xp = "//map[@name=\'"+mapName+"\']";
			var xpathResult = docElement.evaluate(xp, docElement, accessext_NSResolver, XPathResult.FIRST_ORDERED_NODE_TYPE,null);
			if (null != xpathResult) {
				return xpathResult.singleNodeValue;
			} else {
				return null;
			}
		},
		parseNode : function () {
			var i;
			this.baseuri = getBaseURI(this.node);
			this.valid = false;
			
			var titleFromAttribute = GetValueFromAttributes(this.node,['title','alt'],false);
			this.title = findTitleHeaderBeforeNode(this);
			if (this.title == false) {
				this.title = findARIATitleHeaderBeforeNode(this, 2);
				if (this.title == false) { this.title = accessext_getBundleSingleString('noTitle'); }
			}
	
			this.alt = GetValueFromAttributes(this.node,['alt'],accessext_getBundleSingleString('none'));
			
			//Parse links
			this.items = new Array();
			var nodes = this.mapNode.getElementsByTagName('area');
			for (i = 0; i < nodes.length; i++) {
				var n = this.items.length;
				var item = new imageMapItem(nodes[i],n+1);
				if (item.valid) {
					this.items[n] = item;
				}
				if (item.missingRedundantTextLink) { this.missingRedundantTextLink = true; }
				if (item.missingalt) { this.missingalt = true; }
				if (item.emptyalt) { this.emptyalt = true; }
			}
			
			nodes = this.mapNode.getElementsByTagName('a');
			for (i = 0; i < nodes.length; i++) {
				var n = this.items.length;
				var item = new imageMapItem(nodes[i],n+1);
				if (item.valid) {
					this.items[n] = item;
				}
			}
			this.valid = true;
		},
		getTreeItem : function (windoc) {
			return item = accesxt_generateTreeboxResults(document,this);
		},
		listDetailsInHTMLFormat : function () {
			var html = "";
			var colName;
			
			if (this.items.length == 0) { return "&nbsp;"; }
			var obj = this.items[0];
			
			html = html + '<table border=3 title="Image Map ' + (this.order+1) + ' Link Elements"><tr>';
			for (var dataIndex = 0; dataIndex < obj.displayDetails.dataElementNames.length; dataIndex ++) { //for each column to be displayed
				html = html + "<th>" + accessext_getBundleSingleString(obj.displayDetails.columnHeaders[dataIndex]) + "</th>";
			}
			html = html + "</tr>";
			for (var findex = 0; findex < this.items.length; findex ++) { //for each treerow
				if (this.items[findex].display == true) { // && valid
					html = html + "<tr>";
					obj = this.items[findex];
					for (var dataIndex = 0; dataIndex < obj.displayDetails.dataElementNames.length; dataIndex ++) { //for each column to be displayed
						colName = obj.displayDetails.dataElementNames[dataIndex];
						var value = (obj[colName] == null) ? "" : obj[colName].toString();
						html = html + "<td>" + value + "&nbsp;</td>";
					}
					html = html + "</tr>";
				}
			}
			html = html + "</table>";
			return html;
		}	
	}
AccessibilityExtension.LIB.extend(AccessibilityExtension.LIB,
{	
	newImageMapItem: function(node, order) { 
		var n = new imageMapItem(node,order);
		return n; 
	},
	parseImageMap: function(node, loadArray) {
		var obj = new imageMap(node,loadArray.length+1);
		if (obj.valid) {
			loadArray[loadArray.length] = obj;
		}
		return obj.valid;
	},
	
	ParseDocumentForImageMaps: function(docElement, loadArray) {
		var xp = "//img[@usemap]";
		var xpathResult = docElement.evaluate(xp, docElement, accessext_NSResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
		for (var i = 0; i < xpathResult.snapshotLength; i++) {
			parseImageMap(xpathResult.snapshotItem(i), loadArray);
		}
		setMaxSeverityForArray(loadArray);
	},
	
	ParseDocument: function(docElement) {
		ParseDocumentForImageMaps(docElement, AE.primaryarray);
	},
	
	accessext_handle_treebox_main: function() {
		if (AE.treebox_main.currentIndex < 0 || AE.treebox_main.currentIndex >= AE.primaryarray.length) {
			return;
		}
			
		var findex = AE.treebox_main.currentIndex;
		var node = AE.primaryarray[findex].node;
		
		if (node == null || AE.mydoc == null) {
			if (node == null) {
				alert("Node is null");
			}
			return;
		}
		accessext_scrollAndHighlightNode(node);
	
		var gotoButton = document.getElementById('button-goToURL');
		if (gotoButton) {
			gotoButton.disabled = true;
		}
			
		UpdateTreeView();
	},
	
	accessext_handle_treebox: function() {
		var treeChildren = AE.treebox.getElementsByTagName("treechildren");
		
		var node;
		var index = AE.treebox.currentIndex;
		if(index < 0 || index >= AE.dataarray.length || index == null){
			return;
		} else {
			//This snippet is needed for the list of links, since value!=index if duplicates removed
			var value = treeChildren[0].childNodes[index].getAttribute("value");
			node = AE.dataarray[value].node;
			index = value;
		}
		var gotoButton = document.getElementById('button-goToURL');
		if (gotoButton) {
			gotoButton.disabled = false;
		}
		
		//@todo SMF delve deeper into the node to get the shape coordinates
		accessext_treeboxScrollAndHighlightNode(node);
		
		accessext_setNoteText(index);	
	},
	
	UpdateTreeViewMain: function() {
		var sc = document.getElementById(AE.sortColumn_main);
		if (sc == null) {
			accessext_consoleDump("Could not find column: " + AE.sortColumn);
			return;
		}
	//Clear the children and create a new one
		var treeChildren = accessext_clearTreeItems(AE.treebox_main);
		accessext_clearTreeItems(AE.treebox);
		
		//Sort
		//First clear all directions
		var cols = AE.treebox_main.getElementsByTagName("treecols");
		var i;
		if (cols.length == 1) {
			for (i = 0; i < cols[0].childNodes.length; i ++) {
				cols[0].childNodes[i].setAttribute("sortDirection","");
			}
		}
	
		sc.setAttribute("sortDirection", AE.sortDirectionAscending_main ? "ascending" : "descending");
		switch (AE.sortColumn_main) {
			case "list-header-main-order":
				AE.sortProperty="order";
			break;
			case "list-header-main-text":
				AE.sortProperty="title";
			break;
			default:
				AE.sortProperty="order";
			break;
		}
		
		AE.primaryarray.sort(accessext_sortColumnElements);
		
		//Finally add elements to the list
		for (i = 0; i < AE.primaryarray.length; i ++) {
			var item = AE.primaryarray[i].getTreeItem(document);
			item.setAttribute("value", i);
			treeChildren.appendChild(item);
		}
	},
	
	UpdateTreeView: function() {
		try {
			var sc = document.getElementById(AE.sortColumn);
			if (sc == null) {
				accessext_consoleDump("Could not find column: " + AE.sortColumn);
				return;
			}
		//Clear the children and create a new one
			var treeChildren = accessext_clearTreeItems(AE.treebox);
		
			//Modifications for dual-tree view
			var findex = AE.treebox_main.currentIndex;
			if (findex < 0 || findex >= AE.primaryarray.length || findex == null) {
				AE.dataarray = new Array();
			} else {
				AE.dataarray = AE.primaryarray[findex].items;
			}	
			//Sort
			//First clear all directions
			var cols = AE.treebox.getElementsByTagName("treecols");
			var i;
			if (cols.length == 1) {
				for (i = 0; i < cols[0].childNodes.length; i ++)
					cols[0].childNodes[i].setAttribute("sortDirection","");
			}
		
			sc.setAttribute("sortDirection", AE.sortDirectionAscending ? "ascending" : "descending");
			switch (AE.sortColumn) {
				case "list-header-order":
					AE.sortProperty="order";
				break;
				case "list-header-text":
					AE.sortProperty="linkText";
				break;
				case "list-header-link":
					AE.sortProperty="linkHREF";
				break;
				case "list-header-alt":
					AE.sortProperty="alt";
				break;
				case "list-header-redundant":
					AE.sortProperty="redundant";
				break;
				default:
					AE.sortProperty="order";
				break;
			}
			
			AE.dataarray.sort(accessext_sortColumnElements);
			
			//Finally add elements to the list
			for (i = 0; i < AE.dataarray.length; i ++) {
				var item = AE.dataarray[i].getTreeItem(document);
				item.setAttribute("value", i);
				treeChildren.appendChild(item);
			}
		} catch (ex) {
			accessext_consoleDump('UpdateTreeView exception: ', ex);
		}
	},
	
	GoToSelectedURL: function() {
		var theindex = accessext_getActiveValue(AE.treebox);
		
		CleanUp();
		if (theindex < 0) {
			return false;
		}
		var loc = accessext_makeURLAbsolute(AE.dataarray[theindex].node.ownerDocument.location.href,AE.dataarray[theindex].linkHREF);
		
		AE.mydoc.location.href=loc;
		return true;
	},
	
	mapSearchOnKeyPress: function(e) {
		var letter = String.fromCharCode(e.charCode).toLowerCase();
		var index = listboxMap.selectedIndex;
		var i;
		if (letter < 'a' || letter > 'z' || e.altKey || e.metaKey || e.ctrlKey) {
			return;
		}
	
		for (i = index + 1; i<AE.primaryarray.length; i ++) {
			if (AE.primaryarray[i].text.charAt(0).toLowerCase() == letter) {
				listboxMap.selectedIndex = i;
				listboxMap.scrollToIndex(i);
				return;
			}
		}
		for (i = 0; i < index; i ++) {
			if (AE.primaryarray[i].text.charAt(0).toLowerCase() == letter) {
				listboxMap.selectedIndex = i;
				listboxMap.scrollToIndex(i);
				return;
			}
		}
	},
	
	post_InitAccessibilityExt: function() {
		accessext_setNoteText(0);
	}
});
	if (AccessibilityExtension.LIB.InitAccessibilityExt) AccessibilityExtension.LIB.InitAccessibilityExt();		
}});
	